home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / Sample Code / Snippets / Toolbox / NoResDialog / Source / NoResDialog.c
Encoding:
C/C++ Source or Header  |  1996-09-17  |  26.4 KB  |  687 lines  |  [TEXT/CWIE]

  1. // Modified 1994 to show NoResDialog stuff 
  2. // Look for the NoResDialog dialog function 
  3.  
  4. // updates 8/96: changes made to NoResDialog.r so a rsrc file could be created.
  5.  
  6.  
  7. /* Simple.c */
  8. /* The simplest C System 7 shell application */
  9. /* This shell can be very handy for debugging and testing things */
  10. /* Add menu items, add dialogs, add controls, or whatever else you need */
  11. /* This sample contains basic application startup and event loop handling, */
  12. /* add more features as your needs increase. */
  13. /* This sample is High Level Event aware, so you can send and receive AppleEvents */
  14. /* from this application */
  15. /* Written  by C.K. Haun <TR> */
  16. /* Apple Developer Tech Support */
  17. /* October 1991, Tokyo, Japan */
  18. /* Of course, Copyright 1991, Apple Computer Inc. */
  19.  
  20. #include <Dialogs.h>
  21. #include <Fonts.h>
  22. #include <Menus.h>
  23. #include <AppleEvents.h>
  24. #include <Resources.h>
  25. #include <SegLoad.h>
  26. #include "NoResDialog.h"
  27.  
  28. /* prototypes */
  29.  
  30. void InitalizeApp(void);
  31. void DoDiskEvents(long dinfo);                              /* hi word is error code, lo word is drive number */
  32. void DrawMain(WindowPtr drawIt);
  33. Boolean DoSelected(long val);
  34. void SizeMain(WindowPtr theWindow, short how);
  35. void InitAEStuff(void);
  36. void DoHighLevel(EventRecord *AERecord);
  37. void DoDaCall(MenuHandle themenu, long theit);
  38. void DoDocumentClick(WindowPtr theWindow, EventRecord *theEvent);
  39.  
  40. pascal OSErr AEOpenHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn);
  41. pascal OSErr AEOpenDocHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn);
  42. pascal OSErr AEPrintHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn);
  43. pascal OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn);
  44.  
  45. void SampleHelpDialog(void);
  46.  
  47. WindowPtr AddNewWindow(short theID);
  48.  
  49. void NilProc(void);
  50. /* one external */
  51. #ifdef applec
  52.     extern void _DataInit();                                    /* this is the C initialization code */
  53. #endif
  54.  
  55. /* globals */
  56. Boolean gQuit, gInBackground;
  57. unsigned long gMySleep;
  58. ProcessSerialNumber gOurSN;
  59. short gHelpItem;
  60.  
  61. void NoResDialog(void);
  62. pascal void BorderDefault(DialogPtr dwind, short dinum);
  63.  
  64.  
  65. #pragma segment Main
  66. void main()
  67. {
  68.     EventRecord myEventRecord;
  69.     WindowPtr twindow;
  70.     short fHit;
  71.     windowCHandle tempWCH;
  72.     
  73.     #ifdef applec
  74.         UnloadSeg((Ptr)_DataInit);                              /* throw out setup code */
  75.     #endif
  76.     
  77.     InitalizeApp();
  78.     UnloadSeg((Ptr)InitalizeApp);                           /* get rid of my initialization code */
  79.     do {
  80.         WaitNextEvent(everyEvent, &myEventRecord, gMySleep, nil);
  81.         switch (myEventRecord.what) {
  82.             case nullEvent:
  83.                 
  84.                 /* no nul processing in this sample */
  85.                 break;
  86.             case updateEvt:
  87.                 /* always check to see if it's my window */
  88.                 /* this may not seem necessary under 7.0, where it's unlikely or impossible for */
  89.                 /* a DA to be in your layer, but there are others  */
  90.                 /* who can stick themselves into your window list, */
  91.                 /* BalloonWriter comes quickly to mind */
  92.                 if (((WindowPeek)myEventRecord.message)->windowKind == kMyDocumentWindow) {
  93.                     tempWCH = (windowCHandle)GetWRefCon((WindowPtr)myEventRecord.message);
  94.                     ((*tempWCH)->drawMe)((WindowPtr)myEventRecord.message);
  95.                 }
  96.                 break;
  97.             case mouseDown:
  98.                 /* first see where the hit was */
  99.                 fHit = FindWindow(myEventRecord.where, &twindow);
  100.                 switch (fHit) {
  101.                     Rect limitRect;
  102.                     Str255 tempString;
  103.                     long back;
  104.                     case inDesk:                            /* if they hit in desk, then the process manager */
  105.                         break;                              /* will switch us out, we don't need to do anything */
  106.                     case inMenuBar:
  107.                         DoSelected(MenuSelect(myEventRecord.where));
  108.                         break;
  109.                         
  110.                     case inSysWindow:
  111.                         /* pass to the system */
  112.                         SystemClick(&myEventRecord, twindow);
  113.                         break;
  114.                     case inContent:
  115.                         /* Handle content and control clicks here */
  116.                         if (((WindowPeek)myEventRecord.message)->windowKind == kMyDocumentWindow) { /* don't do this unless we have a window open, silly */
  117.                             windowCHandle clicker;
  118.                             clicker = (windowCHandle)GetWRefCon(twindow);
  119.                             /* jump to the content function stored for this window */
  120.                             HLock((Handle)clicker);         /* lock it down so things don't get stupid */
  121.                             ((*clicker)->clickMe)(twindow, &myEventRecord);
  122.                             HUnlock((Handle)clicker);       /* all done */
  123.                         }
  124.                         break;
  125.                     case inDrag:
  126.                         DragWindow(twindow, myEventRecord.where, &qd.screenBits.bounds);
  127.                         break;
  128.                     case inGrow:
  129.                         /* Call GrowWindow here if you have a grow box */
  130.                         SetPort(twindow);
  131.                         limitRect = qd.screenBits.bounds;
  132.                         limitRect.top = kMinHeight;
  133.                         GetWTitle(twindow, tempString);
  134.                         /* I'm not letting the user shrink the window so */
  135.                         /* small that the title is truncated */
  136.                         limitRect.left = StringWidth(tempString) + 120;
  137.                         back = GrowWindow(twindow, myEventRecord.where, &limitRect);
  138.                         
  139.                         if (back) {
  140.                             if (((WindowPeek)myEventRecord.message)->windowKind == kMyDocumentWindow) {
  141.                                 windowCHandle tempWCH = (windowCHandle)GetWRefCon(twindow);
  142.                                 Rect sizeRect = ((WindowPtr)twindow)->portRect;
  143.                                 InvalRect(&sizeRect);
  144.                                 sizeRect.top = sizeRect.bottom - 16;
  145.                                 sizeRect.left = sizeRect.right - 16;
  146.                                 EraseRect(&sizeRect);
  147.                                 InvalRect(&sizeRect);
  148.                                 SizeWindow(twindow, back & 0xffff, back >> 16, true);
  149.                                 ((*tempWCH)->sizeMe)(twindow, fHit);
  150.                             }
  151.                         }
  152.                         InvalRect(&twindow->portRect);
  153.                         
  154.                         break;
  155.                     case inGoAway:
  156.                         /* Click in Close box */
  157.                         if (((WindowPeek)myEventRecord.message)->windowKind == kMyDocumentWindow) {
  158.                             if (TrackGoAway(twindow, myEventRecord.where))
  159.                                 ((*(windowCHandle)((WindowPeek)twindow)->refCon)->closeMe)(twindow);
  160.                         }
  161.                         break;
  162.                     case inZoomIn:
  163.                     case inZoomOut:
  164.                         if (TrackBox(twindow, myEventRecord.where, fHit)) {
  165.                             if (((WindowPeek)myEventRecord.message)->windowKind == kMyDocumentWindow) {
  166.                                 windowCHandle tempWCH = (windowCHandle)GetWRefCon(twindow);
  167.                                 SetPort(twindow);
  168.                                 
  169.                                 ZoomWindow(twindow, fHit, true);
  170.                                 InvalRect(&twindow->portRect);
  171.                                 ((*tempWCH)->sizeMe)(twindow, fHit);
  172.                             }
  173.                         }
  174.                 }
  175.             case mouseUp:
  176.                 /* don't care */
  177.                 break;
  178.                 /* same action for key or auto key */
  179.             case keyDown:
  180.             case autoKey:
  181.                 if (myEventRecord.modifiers & cmdKey)
  182.                     DoSelected(MenuKey(myEventRecord.message & charCodeMask));
  183.                 break;
  184.             case keyUp:
  185.                 /* don't care */
  186.                 break;
  187.             case diskEvt:
  188.                 /* I don't do anything special for disk events, this just passes them */
  189.                 /* to a function that checks for an error on the mount */
  190.                 DoDiskEvents(myEventRecord.message);
  191.                 break;
  192.             case activateEvt:
  193.                 if (myEventRecord.modifiers & activeFlag &&
  194.                     ((WindowPeek)myEventRecord.message)->windowKind == kMyDocumentWindow) {
  195.                     tempWCH = (windowCHandle)GetWRefCon((WindowPtr)myEventRecord.message);
  196.                     ((*tempWCH)->drawMe)((WindowPtr)myEventRecord.message);
  197.                 }
  198.                 break;
  199.             case 10:
  200.                 /* don't care */
  201.                 break;
  202.             case 11:
  203.                 /* don't care */
  204.                 break;
  205.             case 15:
  206.                 switch ((myEventRecord.message >> 24) & 0x0FF) {        /* high byte of message */
  207.                     case suspendResumeMessage:              /* suspend/resume is also an activate/deactivate */
  208.                         gInBackground = (myEventRecord.message & kResumeMask) == 0;
  209.                         if (!gInBackground) {
  210.                             
  211.                         }
  212.                         break;
  213.                 }
  214.                 break;
  215.             default:
  216.                 break;
  217.                 /* This dispatches high level events (AppleEvents, for example) */
  218.                 /* to our dispatch routine.  This is NEW in the event loop for */
  219.                 /* System 7 */
  220.             case kHighLevelEvent:
  221.                 DoHighLevel(&myEventRecord);
  222.                 break;
  223.                 
  224.         }
  225.     }
  226.             while (gQuit != true);
  227.     
  228. }
  229.  
  230. /* DoDaCall opens the requested DA.  It's here as a seperate routine if you'd */
  231. /* like to perform some action or just know when a DA is opened in your */
  232. /* layer.  Can be handy to track memory problems when a DA is opened */
  233. /* with an Option-open */
  234. void DoDaCall(MenuHandle themenu, long theit)
  235. {
  236.     long qq;
  237.     Str255 DAname;
  238.     GetMenuItemText(themenu, theit, DAname);
  239.     qq = OpenDeskAcc(DAname);
  240. }
  241.  
  242. /* end DoDaCall */
  243.  
  244. /* DoDiskEvents just checks the error code from the disk mount, */
  245. /* and puts up the 'Format' dialog (through DIBadMount) if need be */
  246. /* You can do much more here if you care about what disks are */
  247. /* in the drive */
  248. void DoDiskEvents(long dinfo)                               /* hi word is error code, lo word is drive number */
  249. {
  250.     short hival, loval, tommy;
  251.     Point fredpoint =  {
  252.         40, 40
  253.     };
  254.     hival = HiWord(dinfo);
  255.     loval = LoWord(dinfo);
  256.     if (hival != noErr)                                     /* something happened */ {
  257.         tommy = DIBadMount(fredpoint, dinfo);
  258.     }
  259. }
  260.  
  261. /* draws my window.  Pretty simple */
  262. void DrawMain(WindowPtr drawIt)
  263. {
  264.     RgnHandle tempRgn;
  265.     Rect scratchRect;
  266.     BeginUpdate(drawIt);
  267.     SetPort(drawIt);
  268.     MoveTo(20,20);
  269.     DrawString("\p Select NoResDialog from the Test Stuff menu");
  270.     scratchRect = drawIt->portRect;
  271.     scratchRect.top = scratchRect.bottom - 15;
  272.     scratchRect.left = scratchRect.right - 15;
  273.     tempRgn = NewRgn();
  274.     GetClip(tempRgn);
  275.     ClipRect(&scratchRect);
  276.     DrawGrowIcon(drawIt);
  277.     SetClip(tempRgn);
  278.     DisposeRgn(tempRgn);
  279.     
  280.     EndUpdate(drawIt);
  281. }
  282.  
  283. /* my menu action taker.  It returns a Boolean which I usually ignore, but it */
  284. /* mught be handy someday */
  285. /* I usually use it in an application to determine if a keystroke was accepted */
  286. /* by a menu or whether it should be passed along to any other key acceptors */
  287. Boolean DoSelected(long val)
  288. {
  289.     short loval, hival;
  290.     Boolean returnVal = false;
  291.     loval = LoWord(val);
  292.     hival = HiWord(val);
  293.     
  294.     switch (hival) {                                        /* switch off the menu number selected */
  295.         case kAppleMenu:                                    /* Apple menu */
  296.             if (loval != 1) {                               /* if this was not About, it's a DA */
  297.                 DoDaCall(GetMenuHandle(kAppleMenu), loval);
  298.             } else {
  299.                 Alert(kAboutBox, nil);                      /* do about box */
  300.             }
  301.             returnVal = true;
  302.             break;
  303.         case kFileMenu:                                     /* File menu */
  304.             switch (loval) {
  305.                 case kQuitItem:
  306.                     gQuit = true;                           /* only  item */
  307.                     returnVal = true;
  308.                     break;
  309.                 default:
  310.                     break;
  311.             }
  312.             break;
  313.         case kEditMenu:
  314.             /* edit menu junk */
  315.             /* don't care */
  316.             switch (loval) {
  317.             default:
  318.                 break;
  319.             }
  320.             break;
  321.         case kToolsMenu:
  322.             /* add all your test stuff here */
  323.             NoResDialog();
  324.             switch (loval) {
  325.             default:
  326.                 break;
  327.             }
  328.             break;
  329.         case kHMHelpMenuID:                                 /* Defined in Balloons.h */
  330.             /* I only care about this item.  If anything else is returned here, I don't know what */
  331.             /* it is, so I leave it alone.  Remember, the Help Manager chapter says that */
  332.             /* Apple reserves the right to add and change things in the Help menu */
  333.             if (loval == gHelpItem)
  334.                 SampleHelpDialog();
  335.             break;
  336.             
  337.     }
  338.     HiliteMenu(0);
  339.     return(returnVal);
  340. }
  341.  
  342. void DoDocumentClick(WindowPtr theWindow, EventRecord *theEvent)
  343. {
  344. #pragma unused ( theWindow,theEvent)    
  345. }
  346.  
  347. /* InitAEStuff installs my appleevent handlers */
  348. void InitAEStuff(void)
  349. {
  350.     AEinstalls HandlersToInstall[] =  {
  351.         {
  352.             kCoreEventClass, kAEOpenApplication, NewAEEventHandlerProc(AEOpenHandler)
  353.         },  {
  354.             kCoreEventClass, kAEOpenDocuments, NewAEEventHandlerProc(AEOpenDocHandler)
  355.         },  {
  356.             kCoreEventClass, kAEQuitApplication, NewAEEventHandlerProc(AEQuitHandler)
  357.         },  {
  358.             kCoreEventClass, kAEPrintDocuments, NewAEEventHandlerProc(AEPrintHandler)
  359.         }, 
  360.         /* The above are the four required AppleEvents. */
  361.         
  362.     };
  363.     
  364.     OSErr aevtErr = noErr;
  365.     long aLong = 0;
  366.     Boolean gHasAppleEvents = false;
  367.     /* Check this machine for AppleEvents.  If they are not here (ie not 7.0)
  368.     *   then we exit */
  369.     gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &aLong) == noErr);
  370.     /* The following series of calls installs all our AppleEvent Handlers.
  371.     *   These handlers are added to the application event handler list that 
  372.     *   the AppleEvent manager maintains.  So, whenever an AppleEvent happens
  373.     *   and we call AEProcessEvent, the AppleEvent manager will check our
  374.     *   list of handlers and dispatch to it if there is one.
  375.     */
  376.     if (gHasAppleEvents) {
  377.         register qq;
  378.         for (qq = 0; qq < ((sizeof(HandlersToInstall) / sizeof(AEinstalls))); qq++) {
  379.             aevtErr = AEInstallEventHandler(HandlersToInstall[qq].theClass, HandlersToInstall[qq].theEvent,
  380.                                             HandlersToInstall[qq].theProc, 0, false);
  381.             if (aevtErr) {
  382.                 ExitToShell();                              /* just fail, baby */
  383.             }
  384.         }
  385.     } else {
  386.         ExitToShell();
  387.     }
  388. }
  389.  
  390. /* end InitAEStuff */
  391. /* I'm not doing error handling in this sample for clarities sake, you should. Hah, */
  392. /* easy for me to say, huh? */
  393. void DoHighLevel(EventRecord *AERecord)
  394. {
  395.     OSErr myErr;
  396.     myErr = AEProcessAppleEvent(AERecord);
  397.     
  398. }
  399.  
  400. /* end DoHighLevel */
  401.  
  402. /* This is the standard Open Application event.  */
  403. pascal OSErr AEOpenHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn)
  404. {
  405.     WindowPtr myWindow;
  406.  
  407. #pragma unused (messagein,reply,refIn)
  408.     /* we of course don't do anything here in this simple app */
  409.     /* except open our window */
  410.     myWindow = AddNewWindow(kDocWindowResID);
  411.     
  412.     return(noErr);
  413. }
  414.  
  415. /* end AEOpenHandler */
  416.  
  417. /* Open Doc, opens our documents.  Remember, this can happen at application start AND */
  418. /* anytime else.  If your app is up and running and the user goes to the desktop, hilites one */
  419. /* of your files, and double-clicks or selects Open from the finder File menu this event */
  420. /* handler will get called. Which means you don't do any initialization of globals here, or */
  421. /* anything else except open then doc.  */
  422. /* SO-- Do NOT assume that you are at app start time in this */
  423. /* routine, or bad things will surely happen to you. */
  424.  
  425. pascal OSErr AEOpenDocHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn)
  426. {
  427. #pragma unused (messagein,refIn,reply)
  428.     /* we of course don't do anything here */
  429.     return(errAEEventNotHandled);                           /* we have no docs, so no odoc events should come to us */
  430. }
  431.  
  432. pascal OSErr AEPrintHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn)
  433. {                                                           /* no printing handler in yet, so we'll ignore this */
  434.     /* the operation is functionally identical to the ODOC event, with the additon */
  435.     /* of calling your print routine.  */
  436. #pragma unused (messagein,refIn,reply)
  437.     /* we of course don't do anything here */
  438.     return(errAEEventNotHandled);                           /* we have no docs, so no pdoc events should come to us */
  439. }
  440.  
  441. /* Standard Quit event handler, to handle a Quit event from the Finder, for example.  */
  442. /* ••••• DO NOT CALL EXITTOSHELL HERE ••••• or you will never have a happy life.  */
  443. /* OK, it's a few months after I wrote that comment, and I've seen a lot of code */
  444. /* come through DTS that calls ExitToShell from quit handlers.  Let me explain... */
  445. /* When an AppleEvent Handler is called (like this quit handler) you are ALMOST */
  446. /* 100% in your application world.  A5 is right, you can call any toolbox function, */
  447. /* you can call your own routines, everything _seems_ like you are in complete  */
  448. /* control.  Well, almost but not quite.  The routine has been dispatch to from the */
  449. /* AppleEvent Manager's space, so you _must_ return to that at some point! */
  450. /* Which is why you can't call ETS from here.  When you call ExitToShell from an */
  451. /* AE Handler, the most likely thing that happens is the FInder quits, and your  */
  452. /* application keeps running.  Which ain't what you want, y'know? */
  453. /* so, DON'T CALL EXITTOSHELL FROM AN APPLEEVENT HANDLER!!!!!!!!!!!!!! */
  454. pascal OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn)
  455. {
  456. #pragma unused (messagein,refIn,reply)
  457.     gQuit = true;
  458.     return(noErr);
  459. }
  460.  
  461.  
  462. /* This is my sample help dialog.  Does not do anything, expand as you need */
  463. void SampleHelpDialog(void)
  464. {
  465.     DialogPtr tdial = GetNewDialog(kSampHelp, nil, (WindowPtr)-1);
  466.     short itemhit = 0;
  467.     while (itemhit != 1) {
  468.         ModalDialog((ModalFilterProcPtr)nil, &itemhit);
  469.     }
  470.     DisposeDialog(tdial);
  471. }
  472.  
  473.  
  474. #pragma segment Initialize
  475. void InitalizeApp(void)
  476. {
  477.     Handle myMenu;
  478.     MenuHandle helpHandle, appleMenuHandle;
  479.     StringHandle helpString;
  480.     short count;
  481.     long vers;
  482.  
  483.     MaxApplZone();
  484.     InitGraf((Ptr)&qd.thePort);
  485.     InitFonts();
  486.     InitWindows();
  487.     InitMenus();
  488.     TEInit();
  489.     InitDialogs(nil);
  490.     InitCursor();
  491.     /* Check system version */
  492.     Gestalt(gestaltSystemVersion, &vers);
  493.     vers = (vers >> 8) & 0xf;                               /* shift result over and mask out major version number */
  494.     if (vers < 7) {
  495.         StopAlert(kBadSystem, nil);
  496.         ExitToShell();
  497.     }
  498.     InitAEStuff();
  499.     /* set up my menu junk */
  500.     myMenu = GetNewMBar(kMBarID);
  501.     SetMenuBar(myMenu);
  502.     appleMenuHandle = GetMenuHandle(kAppleMenu);
  503.     AppendResMenu(appleMenuHandle, 'DRVR');
  504.     /* now install my Help menu item in the Help Manager's menu */
  505.     HMGetHelpMenuHandle(&helpHandle);                       /* Get the Hlpe menu handle */
  506.     count = CountMItems(helpHandle);                        /* How many items are there? */
  507.     helpString = GetString(kHelpString);                    /* get my help string */
  508.     DetachResource((Handle)helpString);                             /* detach it */
  509.     HNoPurge((Handle)helpString);
  510.     MoveHHi((Handle)helpString);
  511.     HLock((Handle)helpString);
  512.     InsertMenuItem(helpHandle, (ConstStr255Param)helpString, count + 1);       /* insert my item in the Help menu */
  513.     gHelpItem = CountMItems(helpHandle);                    /* The number of the item */
  514.     
  515.     InsertMenu(GetMenu(90), -1);
  516.     DrawMenuBar();
  517.     GetCurrentProcess(&gOurSN);                             /* Get our process serial number for later use, if needed */
  518.     
  519. }
  520.  
  521.  
  522. #pragma segment Main
  523. WindowPtr AddNewWindow(short theID)
  524. {
  525.     windowCHandle setControls;
  526.     WindowPtr tempWP;
  527.     short cnt = 0;
  528.     tempWP = GetNewWindow(theID, 0, (WindowPtr)-1);         /* get a new window */
  529.     ((WindowPeek)tempWP)->windowKind = kMyDocumentWindow;       /* mark it as my document window */
  530.     setControls = (windowCHandle)NewHandleClear(sizeof(windowControl));     /* add our control structure to it */
  531.     SetWRefCon(tempWP, (long)setControls);                  /* stop stuffing refCon directly <ckh 1.0.3> */
  532.     HLock((Handle)setControls);                             /* lock it down while we fill it*/
  533.     
  534.     /* add pointers to our procedures for drawing, saving, and closing */
  535.     /* This way, all I need is one dispatch point for drawing, closing */
  536.     /* or whatever, I don't have to case off the window kind to go to the  */
  537.     /* correct routine.  Kinda like object-oriented programming, but I won't */
  538.     /* admit that. */
  539.     (*setControls)->drawMe = DrawMain;
  540.     (*setControls)->clickMe = DoDocumentClick;
  541.     (*setControls)->sizeMe = SizeMain;
  542.     (*setControls)->generalData = NewHandle(0);
  543.     return(tempWP);
  544. }
  545.  
  546. void SizeMain(WindowPtr theWindow, short how)
  547. {
  548. #pragma unused (how )
  549.     WindowPtr tempWP;
  550.     GetPort(&tempWP);
  551.     InvalRect(&theWindow->portRect);
  552.     SetPort(tempWP);
  553. }
  554.  
  555. void NilProc(void)
  556. {
  557.     
  558. }
  559.  
  560. /* This is a structure I defined to make it easier for me to add a new */
  561. /* dialog item to a DITL  */
  562. /* The definition of this comes from Inside Mac volume I, page 427 */
  563. /* or Inside Mac: Mac Toolbox  Essentials page 6-153 */
  564. typedef struct ditlItemTemplate {
  565.     long placeHolder;
  566.     Rect boundsRect;
  567.     Byte itemType;
  568.     Byte followingCount;
  569. } ditlItemTemplate;
  570.  
  571. /* My function for creating a DITL, creating a dialog, and running the dialog */
  572. /* without using resources */
  573. void NoResDialog(void)
  574. {
  575.  
  576. DialogPtr myDialog;
  577. short hitItem = 0;
  578.  
  579. /* rectangle for our dialog */
  580. Rect theBounds =  { 40, 40, 250, 300};
  581.  
  582. /* rectangles for our two dialog items */
  583.  
  584. Rect theOKRect =  { 100, 100, 120, 160 };
  585.  
  586. Rect thenotOKRect =  {130, 100, 150, 160  };
  587.  
  588.  
  589.     Rect tempRect;                                          /* these  three are here for all the GetDItem/SetDItem calls*/
  590.     short tempItem;
  591.     Handle tempHandle;
  592.  
  593. /* An empty handle that we will build our dialog item list (DITL) in */
  594. Handle ditlList = NewHandle(0);
  595.  
  596. /* scratch variables */
  597. Size currentSize;
  598. Size stringCount;
  599. Str15 theOKword = "\pOK";
  600. short *theDPtr;
  601.  
  602. /* The item template (based on our structure above) that we'll use to create our DITL */
  603. ditlItemTemplate currentItem;
  604.  
  605.  
  606. /* add an OK button to the dialog by hand-building  */
  607. /* a DITL */
  608.  
  609. /* first add the count of items that will be in the DITL */
  610. SetHandleSize(ditlList, 2);
  611. theDPtr = (short *)*ditlList;
  612.  
  613. /* I'm creating a two item list, one for the OK button, the other for the Not OK button */
  614. *theDPtr = 1;
  615.  
  616. /* Set up our first item, the OK button */
  617. currentItem.placeHolder = 0;                            /* always 0 */
  618. currentItem.boundsRect = theOKRect;                     /* rectangle to use */
  619. currentItem.itemType = ctrlItem;                        /* what type of item it is, it's a button */
  620. currentItem.followingCount = theOKword[0];              /* how long the button title is in bytes */
  621.  
  622. /* get the current size of the item list, and append this item definition to the handle */
  623. currentSize = GetHandleSize(ditlList);
  624. SetHandleSize(ditlList, currentSize + sizeof(currentItem));
  625. BlockMove((Ptr)¤tItem, (Ptr)(*ditlList + currentSize), sizeof(currentItem));
  626.  
  627. /* now move the text of the OK word into the handle */
  628. /* NOTE:  It's got to be even, so if the string is odd */
  629. /* I'll actually move one more byte than is there */
  630.  
  631. /* Obviosly I know what it is in this case, I'm just doing this so you'll see */
  632. /* what would need to be done in the generic case */
  633.  
  634. stringCount = theOKword[0];
  635. if (stringCount & 0x1)   /* if odd */
  636.     stringCount++;        /* make even */
  637. currentSize = GetHandleSize(ditlList);
  638. SetHandleSize(ditlList, currentSize + stringCount);    
  639. BlockMove((Ptr)&theOKword[1], (Ptr)(*ditlList + currentSize), stringCount);
  640.  
  641. /* Now add another button, the Not OK button */
  642. currentItem.placeHolder = 0;                            
  643. currentItem.boundsRect = thenotOKRect;              
  644. currentItem.itemType = userItem;                      
  645. currentItem.followingCount =0;                   
  646.  
  647. /* get the current size of the item list, and append this item definition to the handle */
  648. currentSize = GetHandleSize(ditlList);
  649. SetHandleSize(ditlList, currentSize + sizeof(currentItem));
  650. BlockMove((Ptr)¤tItem, (Ptr)(*ditlList + currentSize), sizeof(currentItem));
  651.  
  652.  
  653. /* So, we've built a DITL.  Now we can create the dialog, since we have something to  */
  654. /* pass to it */
  655. /* we're creating it invisibly, since we have to add the drawing proc */
  656. /* for the user item after we create the dialog */
  657. myDialog = NewDialog(nil, &theBounds, nil, false, dBoxProc, (WindowPtr)-1, false, nil, ditlList);
  658.  
  659.             GetDialogItem(myDialog, 2, &tempItem, &tempHandle, &tempRect);
  660.             SetDialogItem(myDialog, 2, tempItem, (Handle)BorderDefault, &tempRect);
  661. ShowWindow(myDialog);
  662. /* run it with ModalDialog! */
  663. do {
  664.     ModalDialog(nil, &hitItem);
  665. }
  666.         while (hitItem != 1);
  667. DisposeDialog(myDialog);
  668. // the Dialog manager has deleted the DITL handle for us
  669. }
  670.  
  671. /* BorderDefault draws a heavy border around the default button (in this case the OK button ) */
  672. /* Again, not necessary if the new DM calls are in */
  673. pascal void BorderDefault(DialogPtr dwind, short dinum)
  674. {
  675. #pragma unused (dinum)
  676.     short itemtype;
  677.     Handle itemhandle;
  678.     Rect borderRect;
  679.     GetDialogItem(dwind, ok, &itemtype, &itemhandle, &borderRect);
  680.     /* ok is defined as 1 in the interfaces.  If you'd like another item outlined, */
  681.     /* change this number, of course. */
  682.     InsetRect(&borderRect, -4, -4);
  683.     PenSize(3, 3);
  684.     FrameRoundRect(&borderRect, 16, 16);
  685.     PenSize(1, 1);
  686. } /* end BorderDefault */
  687.